// Copyright (C) 2022 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
//
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<广西木子科技有限公司>，授权编号：<NT220402151538>，代码指纹：<A.648883738.885>，技术对接人微信：<ID: Lingmuziyi>】
// 【授权寄送：<收件：李先生、地址：南宁市科园西十路11号国电智能大厦1101F、电话：17736659550、邮箱：yingshashou@vip.qq.com>】
//
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
//
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rainbowchat.push.ios;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.utils.LoggerFactory;
import com.x52im.rainbowchat.cache.GroupsInfoCacheProvider;
import com.x52im.rainbowchat.cache.UsersInfoCacheProvider;
import com.x52im.rainbowchat.cache.dto.GroupInfo4Cache;
import com.x52im.rainbowchat.cache.dto.UserInfo4Cache;
import com.x52im.rainbowchat.im.dto.MsgBodyRoot;

/**
 * 用于向iOS的设备进行离线消推送的辅助类。
 *
 * @author Jack Jiang
 * @version 4.3
 */
public class APNSPushHelper {
//	/**
//	 * 尝试向已保存iOS设备token信息的用户进行群聊通知的APNs消息推送。
//	 * 如果缓存中不存在该用户的ios设备token信息，则不需要推送。
//	 *
//	 * @param toUid 要被推送的用户
//	 * @param groupId 发生的群id
//	 * @param content 推送内容
//	 */
//	public static void tryPushGroupCMD(String toUid, String groupId, String content)
//	{
//		String groupName = null;
//		try
//		{
//			// 从缓存出取出该群组的基本信息
//			GroupInfo4Cache g = GroupsInfoCacheProvider.getInstance().get(groupId);
//
//			if(g == null || (groupName = g.getGname())== null || content == null)
//			{
//				throw new IllegalArgumentException("无效的参数g="+g+", groupName="+groupName+", content="+content+"!");
//			}
//
//			//## 尝试向ios设备进行APNs离线消息推送
//			UserInfo4Cache iosTokenInfo = UsersInfoCacheProvider.getInstance().get(toUid);
//			// 用户的Ios 设备token不为空才需要推送
//			if(iosTokenInfo != null && !CommonUtils.isStringEmpty(iosTokenInfo.getIosDeviceToken()))
//			{
//				Http2APNSPusher.getInstance().push(iosTokenInfo.getIosDeviceToken(), null, groupName+":"+content, -1);
//			}
//			else
//			{
//				LoggerFactory.getLog().debug("【向iOS离线推送群CMD】本次无需推送，原因：无用户"+toUid+"的ios设备token数据。"
//						+" {uid="+toUid+",groupId="+groupId+",groupName="+groupName+",content="+content+"}");
//			}
//		}
//		catch (Exception e)
//		{
//			LoggerFactory.getLog().warn("【向iOS离线推送群CMD】推送失败，原因："
//					+e.getMessage()+" {uid="+toUid+",groupName="+groupName+",content="+content+"}", e);
//		}
//	}

    /**
     * 尝试向已保存iOS设备token信息的用户进行聊天消息（包括群聊、陌生一对一、好友一对一聊）的APNs消息推送。
     * 如果缓存中不存在该用户的ios设备token信息，则不需要推送。
     *
     * @param chatType 聊天类型，@see {@link MsgBodyRoot}
     * @param msgType  消息类型，@see {@link MsgBodyRoot}
     * @param content  消息内容
     * @param fromUid  消息发起人
     * @param toUid    消息接收人
     * @param toGid    消息发生的群（如果是群聊消息的话）
     */
    public static void tryPushChattingMessage(int chatType, int msgType, String content, String fromUid, String toUid, String toGid) {
        try {
            if (content == null || fromUid == null || toUid == null) {
                throw new IllegalArgumentException("无效的参数content=" + content + ", fromUid=" + fromUid + ", toUid=" + toUid + "!");
            }

            //## 尝试向ios设备进行APNs离线消息推送
            UserInfo4Cache iosTokenInfo = UsersInfoCacheProvider.getInstance().get(toUid);
            // 用户的Ios 设备token不为空才需要推送
            if (iosTokenInfo != null && !CommonUtils.isStringEmpty(iosTokenInfo.getIosDeviceToken())) {
                String pushContent = null;

                // 如果是群聊
                if (chatType == MsgBodyRoot.CHAT_TYPE_GROUP$CHAT) {
                    GroupInfo4Cache g = GroupsInfoCacheProvider.getInstance().get(toGid);

                    if (g != null) {
                        // 这是群聊的系统通知
                        if (msgType == MsgBodyRoot.TYPE_SYSTEAM$INFO) {
                            pushContent = g.getGname() + ":" + content;
                        }
                        // 这是普通的聊群消息
                        else {
                            UserInfo4Cache u = UsersInfoCacheProvider.getInstance().get(fromUid);
                            if (u != null) {
                                String gname = g.getGname();
                                String fromNickname = u.getNickName();

                                // 形如：”老王(XXX群)：你好啊！“
                                pushContent = fromNickname + "(" + gname + "):" + parseMessageForShow(content, msgType);
                            } else {
                                LoggerFactory.getLog().debug("【向iOS离线推送群聊天消息】本次无需推送，原因：从"
                                        + "缓存中没有查到发送者信息，即toGid=" + toGid + "(" + g + "), fromUid=" + fromUid
                                        + "(" + u + ")的缓存！{chatType=" + chatType + ",msgType=" + msgType + ",content="
                                        + content + ",fromUid" + fromUid + ",toUid=" + toUid + ",toGid=" + toGid + "}");
                                return;
                            }
                        }
                    } else {
                        LoggerFactory.getLog().debug("【向iOS离线推送群聊天消息】本次无需推送，原因：从"
                                + "缓存中没有查到群组息，即toGid=" + toGid + "(" + g + "), fromUid=" + fromUid
                                + "的缓存！{chatType=" + chatType + ",msgType=" + msgType + ",content="
                                + content + ",fromUid" + fromUid + ",toUid=" + toUid + ",toGid=" + toGid + "}");
                        return;
                    }
                }
                // 如果是一对一聊天（陌生人聊天、好友聊天）
                else {
                    UserInfo4Cache u = UsersInfoCacheProvider.getInstance().get(fromUid);
                    if (u != null) {
                        String fromNickname = u.getNickName();

                        // 形如：”老王：你好啊！“
                        pushContent = fromNickname + ":" + parseMessageForShow(content, msgType);
                    } else {
                        LoggerFactory.getLog().debug("【向iOS离线推送一对一聊天消息】本次无需推送，原因：从"
                                + "缓存中没有查到相关缓存，fromUid=" + fromUid
                                + "(" + u + ")的缓存！{chatType=" + chatType + ",msgType=" + msgType + ",content="
                                + content + ",fromUid" + fromUid + ",toUid=" + toUid + ",toGid=" + toGid + "}");
                        return;
                    }
                }

                if (pushContent != null) {
                    Http2APNSPusher.getInstance().push(iosTokenInfo.getIosDeviceToken(), null, pushContent, -1);
                } else {
                    LoggerFactory.getLog().debug("【向iOS离线推送聊天消息】本次无需推送，原因：pushContent=null！"
                            + " {chatType=" + chatType + ",msgType=" + msgType + ",content="
                            + content + ",fromUid" + fromUid + ",toUid=" + toUid + ",toGid=" + toGid + "}");
                }
            } else {
                LoggerFactory.getLog().debug("【向iOS离线推送聊天消息】本次无需推送，原因：无该用户" + toUid + "的ios设备token数据。"
                        + " {chatType=" + chatType + ",msgType=" + msgType + ",content="
                        + content + ",fromUid" + fromUid + ",toUid=" + toUid + ",toGid=" + toGid + "}");
            }
        } catch (Exception e) {
            LoggerFactory.getLog().warn("【向iOS离线推送聊天消息】推送失败，原因："
                    + e.getMessage() + " {chatType=" + chatType + ",msgType=" + msgType + ",content="
                    + content + ",fromUid" + fromUid + ",toUid=" + toUid + ",toGid=" + toGid + "}", e);
        }
    }

    /**
     * 尝试向加好友被请求者发送ios的离线推送送通知。
     *
     * @param toUid   被请求者
     * @param fromUid 好友请求发起者
     */
    public static void tryPushAddFriendProcess_request(String toUid, String fromUid) {
        UserInfo4Cache u = UsersInfoCacheProvider.getInstance().get(fromUid);
        if (u != null) {
            String fromNickname = u.getNickName();
            _tryPushAddFriendProcess(toUid, fromNickname + " 请求加你为好友", "【向iOS离线推送-请求加好友】");
        } else {
            LoggerFactory.getLog().debug("【向iOS离线推送-请求加好友】 本次无需推送，原因：从"
                    + "缓存中没有查到相关缓存，fromUid=" + fromUid + "(" + u + ")的缓存！{toUid=" + toUid + "}");
            return;
        }
    }

    /**
     * 尝试发出被加者拒绝加好请求的ios离线通知。
     *
     * @param friendNickname 被加者的昵称
     * @param srcUid         加友发起人（也就是本次要通知的对象）
     */
    public static void tryPushAddFriendProcess_reject(String friendNickname, String srcUid) {
        _tryPushAddFriendProcess(srcUid, friendNickname + " 拒绝了你的好友请求", "【向iOS离线推送-拒绝加好友】");
    }

    /**
     * 尝试发出加好请求成功的ios离线通知（给请求发起者）。
     *
     * @param fromUid        好友请求发起者（也就是本次要通知的对象）
     * @param friendNickname 被加者的昵称
     */
    public static void tryPushAddFriendProcess_accept(String srcUid, String friendNickname) {
        _tryPushAddFriendProcess(srcUid, friendNickname + " 已同意你的好友请求", "【向iOS离线推送-同意加好友】");
    }

    /**
     * 尝试向已保存iOS设备token信息的用户进行添加好友（包括：发出好友请求、同意请求、拒绝请求）
     * 相关通知的APNs消息推送。
     * <p>
     * 如果缓存中不存在该用户的ios设备token信息，则不需要推送。
     *
     * @param toUid   要被推送的用户
     * @param content 推送内容
     */
    private static void _tryPushAddFriendProcess(String toUid, String content, String TAG) {
        try {
            if (toUid == null || content == null) {
                throw new IllegalArgumentException("无效的参数toUid=" + toUid + ", content=" + content + "!");
            }

            //## 尝试向ios设备进行APNs离线消息推送
            UserInfo4Cache iosTokenInfo =
                    UsersInfoCacheProvider.getInstance().get(toUid);
            // 用户的Ios 设备token不为空才需要推送
            if (iosTokenInfo != null && !CommonUtils.isStringEmpty(iosTokenInfo.getIosDeviceToken())) {
                Http2APNSPusher.getInstance().push(
                        iosTokenInfo.getIosDeviceToken(), null, content, -1);
            } else {
                LoggerFactory.getLog().debug(TAG + " 本次无需推送，原因：无用户" + toUid + "的ios设备token数据。"
                        + " {uid=" + toUid + ",content=" + content + "}");
            }
        } catch (Exception e) {
            LoggerFactory.getLog().warn(TAG + " 推送失败，原因："
                    + e.getMessage() + " {uid=" + toUid + ",content=" + content + "}", e);
        }
    }

    /**
     * 根据消息类型，显示友好的文字内容供某些情况下的预览（比如首页”消息“列表中、系统通知等）.
     */
    private static String parseMessageForShow(String messageContent, int msgType) {
        if (messageContent == null) {
            return "";
        }

        String messageContentForShow = "";
        switch (msgType) {
            case MsgBodyRoot.TYPE_IMAGE:
                messageContentForShow = "[图片]";
                break;
            case MsgBodyRoot.TYPE_VOICE:
                messageContentForShow = "[语音]";
                break;
            case MsgBodyRoot.TYPE_GIFT$SEND:
                messageContentForShow = "[收到礼物]";
                break;
            case MsgBodyRoot.TYPE_GIFT$GET:
                messageContentForShow = "[能送我个礼物吗？]";
                break;
            case MsgBodyRoot.TYPE_FILE:
                messageContentForShow = "[文件]";
                break;
            case MsgBodyRoot.TYPE_SHORTVIDEO:
                messageContentForShow = "[短视频]";
                break;
            case MsgBodyRoot.TYPE_CONTACT:
                messageContentForShow = "[个人名片]";
                break;
            case MsgBodyRoot.TYPE_LOCATION:
                messageContentForShow = "[位置]";
                break;
            case MsgBodyRoot.TYPE_RED_ENVELOPE:
                messageContentForShow = "[红包消息]";
                break;
            case MsgBodyRoot.TYPE_DIRECT_UID:
                // {"uid":"", "text":"ok"} 只返回text节点的文字
                JSONObject jsonObject = JSON.parseObject(messageContent);
                messageContentForShow = jsonObject.getString("text");
                break;
            case MsgBodyRoot.TYPE_REVOKE:
                messageContentForShow = "撤回了一条消息";
                break;
            default:
                messageContentForShow = messageContent;
                break;
        }

        return messageContentForShow;
    }


}
